package com.wenx.v3system.modular.oauth.service.impl;

import com.wenx.v3system.modular.oauth.dto.OAuth2TokenResponseDto;
import com.wenx.v3system.modular.oauth.prop.OAuth2ClientProp;
import com.wenx.v3system.modular.oauth.service.OAuth2TokenService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.Map;

/**
 * OAuth2令牌服务实现类
 * 
 * @author wenx
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OAuth2TokenServiceImpl implements OAuth2TokenService {

    private final OAuth2ClientProp oauth2ClientProp;
    
    @Qualifier("oauth2LoadBalancedRestTemplate")
    private final RestTemplate loadBalancedRestTemplate;

    @Override
    public OAuth2TokenResponseDto exchangeToken(String authorizationCode, String clientIp) {
        try {
            String tokenUrl = oauth2ClientProp.getBaseUrl() + oauth2ClientProp.getTokenEndpoint();
            
            // 构建请求参数
            MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
            params.add("grant_type", "authorization_code");
            params.add("code", authorizationCode);
            params.add("client_id", oauth2ClientProp.getClientId());
            params.add("client_secret", oauth2ClientProp.getClientSecret());
            params.add("redirect_uri", oauth2ClientProp.getRedirectUri());
            
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
            
            HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(params, headers);
            
            ResponseEntity<Map> response = loadBalancedRestTemplate.postForEntity(tokenUrl, requestEntity, Map.class);
            
            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> tokenData = response.getBody();
                
                OAuth2TokenResponseDto tokenResponse = OAuth2TokenResponseDto.builder()
                        .accessToken((String) tokenData.get("access_token"))
                        .refreshToken((String) tokenData.get("refresh_token"))
                        .tokenType((String) tokenData.get("token_type"))
                        .expiresIn((Integer) tokenData.get("expires_in"))
                        .scope((String) tokenData.get("scope"))
                        .build();
                
                // 获取用户信息
                if (tokenResponse.getAccessToken() != null) {
                    try {
                        enrichUserInfo(tokenResponse);
                    } catch (Exception e) {
                        log.warn("获取用户信息失败: {}", e.getMessage());
                    }
                }
                
                return tokenResponse;
            } else {
                throw new RuntimeException("令牌交换失败，HTTP状态: " + response.getStatusCode());
            }
            
        } catch (Exception e) {
            throw new RuntimeException("令牌交换失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取用户信息
     */
    private void enrichUserInfo(OAuth2TokenResponseDto tokenResponse) {
        try {
            String userInfoUrl = oauth2ClientProp.getBaseUrl() + "/oauth2/userinfo";
            
            HttpHeaders headers = new HttpHeaders();
            headers.setBearerAuth(tokenResponse.getAccessToken());
            headers.setContentType(MediaType.APPLICATION_JSON);
            
            HttpEntity<String> requestEntity = new HttpEntity<>(headers);
            
            ResponseEntity<Map> response = loadBalancedRestTemplate.exchange(
                    userInfoUrl, HttpMethod.GET, requestEntity, Map.class);
            
            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> userData = response.getBody();
                
                tokenResponse.setUsername((String) userData.get("username"));
                tokenResponse.setName((String) userData.get("name"));
                tokenResponse.setEmail((String) userData.get("email"));
                tokenResponse.setSubject((String) userData.get("sub"));
            }
            
        } catch (Exception e) {
            log.error("用户信息获取异常", e);
        }
    }
} 